<script setup>
import {onMounted, reactive, ref} from "vue";
import {DeleteFilled, FolderAdd} from "@element-plus/icons-vue";
import {useRoute} from "vue-router";
import Selector from "@/components/Question/QuestionSelector.vue"
import router from "@/router/index.js";
import {
  addContestBaseInfoService,
  addContestOjQuestionService, deleteContestOjQuestionService,
  editContestOjQuestionService, publishContestService, sortContestOjQuestionService,
  updateContestOjQuestionService
} from "@/api/contest.js";
import {ElMessage, ElMessageBox} from "element-plus";
import {getOjQuestionList} from "@/api/question.js";
import draggable from 'vuedraggable'

const type = useRoute().query.type
const totalSize = ref(0)
const ojQuestionList = ref([])
const ojQuestionIdSet = ref([])
const dialogVisible = ref(false)
const formParams = reactive({
  id: "",
  title: "",
  raceDate: ""
})

const params = reactive({
  current: 1,
  size: 10,
  idStr: "",
  title: "",
  difficulty: ""
})

// -1 代表返回上一级路由
function goBack() {
  router.go(-1);
}

async function onSaveBaseInfo() {
  const fd = new FormData()
  for (let key in formParams) {
    if (key === 'raceDate') {
      fd.append('beginTime', formParams.raceDate[0])
      fd.append('endTime', formParams.raceDate[1])
    } else if (key !== 'beginTime' && key !== 'endTime') {
      fd.append(key, formParams[key])
    }
  }
  // 发送添加竞赛基本信息请求
  try {
    if (formParams.id) {
      await updateContestOjQuestionService(fd)
    } else {
      const result = await addContestBaseInfoService(fd)
      formParams.id = result.data.id
    }
  } catch (error) {
    console.log(error)
  }
  ElMessage({
    message: '保存竞赛基本信息成功！',
    type: 'success',
  })
}

async function getOjQuestionListForRace() {
  // 获取Oj题目列表
  if (Array.isArray(editOjList.ojQuestionContestList) && editOjList.ojQuestionContestList.length > 0) {
    const idString = editOjList.ojQuestionContestList
        .map(item => item.id) // 提取id字段
        .join(",")
    params.idStr = idString
    console.log(idString)
  }
  const result = await getOjQuestionList(params)
  ojQuestionList.value = result.data.records
  totalSize.value = result.data.total
}

function addOjQuestion() {
  // 添加题目，向后端请求OJ题目列表
  if (formParams.id === null || formParams.id === '') {
    ElMessage.error("请求先保存竞赛基本信息");
    document.querySelector('#raceDiv').focus()
  } else {
    getOjQuestionListForRace()
    dialogVisible.value = true
  }
}

// 处理多选框选中的OJ题目
function handleRowSelect(selection) {
  ojQuestionIdSet.value = []
  selection.forEach(each => {
    ojQuestionIdSet.value.push(each.id)
  });
}

// 处理多选框，选中题目，向竞赛中添加题目
async function submitSelectQuestion() {
  if (ojQuestionIdSet.value && ojQuestionIdSet.value.length < 1) {
    ElMessage.error("请先选择需要向竞赛中添加的OJ题目");
    return;
  }
  const contestData = reactive({
    contestId: formParams.id,
    ojQuestionIdsList: ojQuestionIdSet.value
  })
  await addContestOjQuestionService(contestData)
  // 使弹窗消失
  dialogVisible.value = false
  await getContestOjQuestionById(formParams.id)
  ElMessage.success("添加竞赛OJ题目成功")
}

const editOjList = reactive({
  ojQuestionContestList: []
})

let indexToSortDescMap = new Map()

// 根据竞赛ID获取竞赛中OJ题目详情
async function getContestOjQuestionById(id) {
  const editData = reactive({
    id: id
  })
  const editResult = await editContestOjQuestionService(editData)
  editOjList.ojQuestionContestList = editResult.data.ojQuestionContestList
  Object.assign(formParams, editResult.data)
  formParams.raceDate = [editResult.data.beginTime, editResult.data.endTime]

  // 每获取一次竞赛详情数据，就维护一次下标与元素sortDesc字段的关系
  if (Array.isArray(editOjList.ojQuestionContestList) && editOjList.ojQuestionContestList.length > 0) {
    indexToSortDescMap.clear()
    editOjList.ojQuestionContestList.forEach((item, index) => {
      indexToSortDescMap.set(index, item.sortDesc)
    })
  }
}

onMounted(async () => {
  const id = useRoute().query.id
  if (id) {
    formParams.id = id
    await getContestOjQuestionById(id)
  }
})

async function deleteRaceQuestion(contestId, questionId) {
  try {
    await ElMessageBox.confirm(
        '确定要删除竞赛中该道OJ题吗?',
        '警告',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        }
    )
    const deleteForm = reactive({
      contestId: contestId,
      questionId: questionId
    })
    await deleteContestOjQuestionService(deleteForm)
    await getContestOjQuestionById(contestId)
    ElMessage.success("删除竞赛OJ题目成功")
  } catch (error) {
    if (error === "cancel") {
    }
  }
}

// 拖动结束之后，进行重新设置sortDesc的值
async function handleSortEnd() {
  editOjList.ojQuestionContestList.forEach((item, index) => {
    const originalSortDesc = indexToSortDescMap.get(index)
    item.sortDesc = originalSortDesc
  })

  // 向后端发送请求，重新设置sortDesc
  const sortForm = reactive({
    id: formParams.id,
    ojQuestionContestList: editOjList.ojQuestionContestList
  })
  await sortContestOjQuestionService(sortForm)
  ElMessage.success("排序竞赛OJ题目成功")
}

async function publishContest() {
  const publishForm = reactive({
    id: formParams.id
  })
  await publishContestService(publishForm)
  ElMessage.success("发布竞赛成功")
  router.push("/admin/system/race")
}

async function handlePageChange() {
  const result = await getOjQuestionList(params)
  ojQuestionList.value = result.data.records
  totalSize.value = result.data.total
}

function handleSizeChange() {
  params.current = 1
  handlePageChange()
}

function handleCurrentChange() {
  handlePageChange()
}

function onSearch() {
  if (params.title.toString().trim() === "") {
    ElMessage({
      message: '请输入要搜索题⽬标题，再进行查询！',
      type: 'warning',
    })
    return;
  }
  params.current = 1
  handlePageChange()
}

function onReset() {
  params.current = 1
  params.size = 10
  params.title = ""
  params.difficulty = ""
  handlePageChange()
}
</script>

<template>
  <div class="add-exam-component-box">
    <div class="add-exam-component">
      <!-- 竞赛信息模块 -->
      <div class="exam-base-info-box">
        <!-- 标题 -->
        <div class="exam-base-title">
          <span class="base-title">{{ type === 'add' ? '添加竞赛' : '编辑竞赛' }}</span>
          <el-button class="go-back" type="text" @click="goBack">
            <i class="el-icon-arrow-left"></i> 返回
          </el-button>
        </div>
        <!-- 基本信息 -->
        <div class="exam-base-info">
          <div class="group-box">
            <div class="group-item">
              <!-- 这里有一个 required属性，需要强制进行选择-->
              <div class="item-label required">竞赛名称</div>
              <div>
                <el-input id="raceDiv" v-model="formParams.title" style="width:420px"
                          placeholder="请填写竞赛名称"></el-input>
              </div>
            </div>
          </div>
          <div class="group-box">
            <div class="group-item">
              <div class="item-label required">竞赛周期</div>
              <div>
                <el-date-picker v-model="formParams.raceDate" :disabledDate="disabledDate" type="datetimerange"
                                start-placeholder="竞赛开始时间" end-placeholder="竞赛结束时间"
                                value-format="YYYY-MM-DD HH:mm:ss"/>
              </div>
            </div>
          </div>
          <div class="group-box">
            <div class="group-item">
              <el-button class="exam-base-info-button" type="primary" plain @click="onSaveBaseInfo">保存</el-button>
            </div>
          </div>
        </div>
      </div>

      <!-- 已经向竞赛中添加过的题目列表，这里是已添加竞赛详情展示 -->
      <div class="exam-select-question-box">
        <!-- 添加题目按钮 -->
        <div class="action-row">
          <el-button
              class="exam-add-question"
              :icon="FolderAdd"
              type="text"
              @click="addOjQuestion">
            添加题目
          </el-button>
        </div>
        <!-- 标题行 -->
        <div class="header-row">
          <div class="header-id">题目ID</div>
          <div class="header-title">题目标题</div>
          <div class="header-difficulty">题目难度</div>
          <div class="header-action">操作</div>
        </div>
        <!-- 可拖拽内容 -->
        <draggable
            v-model="editOjList.ojQuestionContestList"
            group="questions"
            item-key="id"
            class="question-select-list"
            ghost-class="dragging"
            animation="200"
            @end="handleSortEnd">
          <template #item="{ element }">
            <div class="draggable-row">
              <div class="row-id">{{ element.id }}</div>
              <div class="row-title">{{ element.title }}</div>
              <div class="row-difficulty">
                <div v-if="element.difficulty === 0" class="difficulty easy">简单</div>
                <div v-if="element.difficulty === 1" class="difficulty medium">中等</div>
                <div v-if="element.difficulty === 2" class="difficulty hard">困难</div>
              </div>
              <div class="row-action">
                <el-button
                    circle
                    type="text"
                    @click="deleteRaceQuestion(formParams.id, element.id)"
                    :icon="DeleteFilled"
                ></el-button>
              </div>
            </div>
          </template>
        </draggable>
      </div>

      <!-- 添加题目弹窗列表，用于展示向某个竞赛中，添加OJ题目列表，下面是弹窗 -->
      <div>
        <el-dialog v-model="dialogVisible">
          <div class="exam-list-box">
            <div class="exam-list-title required">请选择竞赛题目</div>
            <el-form inline="true">
              <el-form-item label="题目难度">
                <Selector @change="handlePageChange" v-model="params.difficulty" style="width: 120px;"></Selector>
              </el-form-item>
              <el-form-item label="题目名称">
                <el-input v-model="params.title" placeholder="请您输入要搜索的题目标题"/>
              </el-form-item>
              <el-form-item>
                <el-button @click="onSearch" plain>搜索</el-button>
                <el-button @click="onReset" plain type="info">重置</el-button>
              </el-form-item>

            </el-form>
            <!-- 题目列表 -->
            <el-table :data="ojQuestionList" @select="handleRowSelect">
              <!-- type=selection是多选框-->
              <el-table-column type="selection"></el-table-column>
              <el-table-column prop="id" label="题目ID"/>
              <el-table-column prop="title" label="题目标题"/>
              <el-table-column prop="difficulty" label="题目难度">
                <template #default="{ row }">
                  <div v-if="row.difficulty === 0" style="color:#3EC8FF;">简单</div>
                  <div v-if="row.difficulty === 1" style="color:#FE7909;">中等</div>
                  <div v-if="row.difficulty === 2" style="color:#FD4C40;">困难</div>
                </template>
              </el-table-column>
            </el-table>
            <!-- 分页区域 -->
            <div class="exam-question-list-button">
              <el-pagination background size="small" layout="total, sizes, prev, pager, next, jumper"
                             :total="totalSize"
                             v-model:current-page="params.current"
                             v-model:page-size="params.size"
                             :page-sizes="[1, 5, 10, 15, 20]"
                             @size-change="handleSizeChange"
                             @current-change="handleCurrentChange"/>
              <el-button class="question-select-submit" type="primary" plain
                         @click="submitSelectQuestion">提交
              </el-button>
            </div>
          </div>
        </el-dialog>
      </div>

      <!-- 提交任务区域 -->
      <div class="submit-box absolute">
        <el-button type="info" plain @click="goBack">取消</el-button>
        <el-button type="primary" plain @click="publishContest">发布竞赛</el-button>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.add-exam-component-box {
  height: 100%;
  overflow: hidden;
  position: relative;
}

.exam-list-box {
  background: #fff;
  padding: 20px 24px;

  .question-select-submit {
    margin-left: 0;
    margin-top: 20px;
    width: 100%;
  }

  .exam-list-title {
    font-size: 14px;
    color: rgba(0, 0, 0, 0.85);
    position: relative;
    padding: 15px 20px;
    padding-top: 0;

    &.required::before {
      position: absolute;
      content: '*';
      font-size: 20px;
      color: red;
      left: 10px;
    }
  }
}

.add-exam-component {
  width: 100%;
  background: #fff;
  padding-bottom: 120px;
  overflow-y: auto;
  box-sizing: border-box;
  height: calc(100vh - 50px);
  margin-top: -10px;

  .exam-select-question-box {
    background: #fff;
    border-radius: 4px;
    padding: 10px;
    width: 100%;

    .action-row {
      text-align: right;
      margin-bottom: 10px;
    }

    .exam-add-question {
      font-size: 14px;
      margin-right: 50px;
    }

    .header-row {
      display: flex;
      align-items: center;
      padding: 10px 15px;
      font-weight: bold;
      background-color: #7fb6f1;
      color: #fff;
      border-bottom: 1px solid #ebeef5;
    }

    .header-id {
      width: 180px;
      text-align: center;
    }

    .header-title {
      flex: 1;
      text-align: left;
      margin-left: 50px;
    }

    .header-difficulty {
      width: 80px;
      text-align: center;
    }

    .header-action {
      width: 80px;
      text-align: center;
    }

    .question-select-list {
      width: 100%;
      margin-top: 10px;
      border: 1px solid #ebeef5;
      border-radius: 4px;
      overflow: hidden;
    }

    .dragging {
      opacity: 0.8;
      transform: scale(1.02);
      background: #f5f5f5;
    }

    .draggable-row {
      display: flex;
      align-items: center;
      padding: 10px 15px;
      border-bottom: 1px solid #ebeef5;
    }

    .draggable-row:last-child {
      border-bottom: none;
    }

    .row-id {
      width: 180px;
      text-align: center;
      color: #6a6969;
    }

    .row-title {
      flex: 1;
      text-align: left;
      margin-left: 50px;
      color: #6a6969;
    }

    .row-difficulty {
      width: 80px;
      text-align: center;
    }

    .row-action {
      width: 80px;
      text-align: center;
    }

    .difficulty {
      padding: 2px 6px;
      border-radius: 4px;
      font-size: 15px;
      text-align: center;
    }

    .difficulty.easy {
      color: #3ec8ff;
      background: #eaf8ff;
    }

    .difficulty.medium {
      color: #fe7909;
      background: #fff3e0;
    }

    .difficulty.hard {
      color: #fd4c40;
      background: #ffecea;
    }
  }

  .exam-base-info-box {
    background: #fff;
    border-bottom: 1px solid #fff;
    border-radius: 2px;
    margin-bottom: 10px;
    width: 100%;
    box-sizing: border-box;

    .exam-base-title {
      display: flex;
      justify-content: space-between;
      align-items: center;
      background-color: #65aefa;
      color: #fff;
      padding: 12px 20px;
      border-radius: 10px;
      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
      margin-bottom: 20px;

      .base-title {
        font-size: 22px;
        font-weight: 600;
        color: #fff;
        letter-spacing: 1px;
        text-align: left;
      }

      .go-back {
        font-size: 18px;
        font-weight: 500;
        color: #ffffff;
        display: flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
        padding: 6px 16px;
        margin-top: 10px;
        border-radius: 4px;
        transition: all 0.3s ease;

        &:hover {
          background-color: rgba(255, 255, 255, 0.1);
          color: #ffa9a9;
        }

        i {
          margin-right: 8px;
          font-size: 16px;
        }
      }
    }

    .exam-base-info {
      box-sizing: border-box;
      border-bottom: 1px solid #e9e9e9;
    }

    .mesage-list-content {
      box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.1);
      background-color: rgba(255, 255, 255, 1);
      border-radius: 10px;
      width: 1200px;
      margin-top: 20px;
    }
  }

  .group-box {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: calc(100% - 64px);
    margin: 24px 0;

    .group-item {
      display: flex;
      align-items: center;
      width: 100%;

      .exam-base-info-button {
        margin-left: 234px;
        width: 120px;
      }

      .item-label {
        font-size: 14px;
        font-weight: 400;
        width: 94px;
        text-align: left;
        color: rgba(0, 0, 0, 0.85);
        position: relative;
        padding-left: 10px;

        &.required::before {
          position: absolute;
          content: '*';
          font-size: 20px;
          color: red;
          left: 0px;
          top: -2px;
        }
      }
    }
  }

  .submit-box {
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;

    &.absolute {
      position: absolute;
      width: calc(100% - 48px);
      bottom: 0;
      background: #fff;
      z-index: 999;
    }
  }

}
</style>